//
//  NSDictionary+JSONString.m
//  iOS-Categories (https://github.com/shaojiankui/iOS-Categories)
//
//  Created by Jakey on 15/4/25.
//  Copyright (c) 2015年 www.skyfox.org. All rights reserved.
//

#import "NSDictionary+JSONString.h"

@implementation NSDictionary (JSONString)
/**
 *  @brief NSDictionary转换成JSON字符串
 *
 *  @return  JSON字符串
 */
-(NSString *)JSONString{
    NSError *error = nil;
    NSString *jsonString=@"";
    if (@available(iOS 11.0, *)) {
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
                                                           options:NSJSONWritingSortedKeys
                                                             error:&error];
        if (jsonData == nil) {
#ifdef DEBUG
            NSLog(@"fail to get JSON from dictionary: %@, error: %@", self, error);
#endif
            return nil;
        }
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }else{
        jsonString = [NSDictionary jsonStringWithDict:self ascend:@"YES"];
    }
    return jsonString;
}

//字典排序
+(NSMutableDictionary*)sortedDictionary:(NSDictionary *)dict{
      
      //将所有的key放进数组
      NSArray *allKeyArray = [dict allKeys];
      //序列化器对数组进行排序的block 返回值为排序后的数组
      NSArray *afterSortKeyArray = [allKeyArray sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id
                                                                                               _Nonnull obj2) {
      
        //注意:compare方法是区分大小写的,即按照ASCII排,排序操作
          NSComparisonResult resuest = [obj1 compare:obj2];
          return resuest;
      }];
      //排序好的字典keys
      NSLog(@"afterSortKeyArray:%@",afterSortKeyArray);
      //通过排列的key值
      NSMutableDictionary *resultDict = [NSMutableDictionary dictionary];
      for (NSString *key in afterSortKeyArray) {
          //格式化一下 防止有些value不是string
          NSString *valueString = [NSString stringWithFormat:@"%@",[dict objectForKey:key]];
          if(valueString.length>0){
              [resultDict setValue:valueString forKey:key];
          }
      }
      return resultDict;
}


+(NSString*)jsonStringWithDict:(NSDictionary*)dict ascend:(NSString *)asc{
    NSArray*keys = [dict allKeys];
    if (keys.count==0) {
        return nil;
    }
    
    int flag=0;// 在拼接json的时候判断是不是字典来判断是不要双引号
    NSArray*sortedArray;
    NSString*str =@"{\"";// 拼接json的转换的结果
    
    // 自定义比较器来比较key的ASCII码
    sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1,id obj2) {
        return[obj1 compare:obj2 options:NSNumericSearch];//升序排序
    }];
    
    // 逐个取出key和value，然后拼接json
    for (int i=0; i<sortedArray.count; i++) {
        
        NSString *categoryId;
        
        if ([asc isEqualToString:@"YES"]) {// 升序排序
            categoryId = sortedArray[i];
        }else{ // 降序排序
            categoryId = sortedArray[sortedArray.count-1-i];
        }
        id value = [dict objectForKey:categoryId];
        
        if([value isKindOfClass:[NSDictionary class]]) {
            flag=1;
            value = [self jsonStringWithDict:value ascend:asc];
        }
        
        // 拼接json串的分割符
        if([str length] !=2) {
            str = [str stringByAppendingString:@",\""];
        }
        // 对数组类型展开处理
        if([value isKindOfClass:[NSArray class]]){
            str = [str stringByAppendingFormat:@"%@\":[",categoryId];
            str = [self sortInner:value jsonString:str];
            // 因为在 处理完数组类型后，json已经拼接好，直接拼接下一个串
            continue;
        }
        if (flag==1) {
            str = [str stringByAppendingFormat:@"%@\":%@",categoryId,value];
            flag=0;
        }else{
            if(![value isKindOfClass:[NSString class]]){// 如果是number类型，value不需要加双引号
                // 如果是BOOl类型则转化为false和true
                Class c = [value class];
                NSString * s = [NSString stringWithFormat:@"%@", c];
                if([s isEqualToString:@"__NSCFBoolean"]){
                    
                    if ([value isEqualToNumber:@YES]) {
                        str = [str stringByAppendingFormat:@"%@\":%@",categoryId,@"true"];
                        
                    }else{
                        str = [str stringByAppendingFormat:@"%@\":%@",categoryId,@"false"];
                    }
                }else{
                    str = [str stringByAppendingFormat:@"%@\":%@",categoryId,value];
                }
            }else{
                str = [str stringByAppendingFormat:@"%@\":\"%@\"",categoryId,value];
            }
        }
    }
    str = [str stringByAppendingString:@"}"];
    NSLog(@"result json = %@", str);
    return str;
}

+(NSString *)sortInner:(NSArray *) array jsonString:(NSString *)json{
    NSString *string =@"";
    NSInteger location = 0;
    for (int i=0; i< array.count; i++) {
        
        if(i!=0&&i< array.count) {
            json = [json stringByAppendingString:@","];
        }
        
        id arr = [array objectAtIndex:i];
        if([arr isKindOfClass:[NSDictionary class]]){// 如果数组里包含字典，则对该字典递归排序
            location = i;
            string=[self jsonStringWithDict:arr ascend:@"YES"];
            json = [json stringByAppendingFormat:@"%@",string];
        }else{
            if([arr isKindOfClass:[NSString class]]){
                json = [json stringByAppendingFormat:@"\"%@\"",arr];
            }else{
                // 如果是BOOl类型则转化为false和true
                Class c = [arr class];
                NSString * s = [NSString stringWithFormat:@"%@", c];
                if([s isEqualToString:@"__NSCFBoolean"]){
                    
                    if ([arr isEqualToNumber:@YES]) {
                        json = [json stringByAppendingFormat:@"%@",@"true"];
                        
                    }else{
                        json = [json stringByAppendingFormat:@"%@",@"false"];
                    }
                }else{
                    json = [json stringByAppendingFormat:@"%@",arr];
                }
                
            }
        }
    }
    
    json = [json stringByAppendingString:@"]"];
    return json;
}

/**
 *  @brief  将url参数转换成NSDictionary
 *
 *  @param query url参数
 *
 *  @return NSDictionary
 */
+ (NSDictionary *)dictionaryWithURLQuery:(NSString *)query
{
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    NSArray *parameters = [query componentsSeparatedByString:@"&"];
    for(NSString *parameter in parameters) {
        NSArray *contents = [parameter componentsSeparatedByString:@"="];
        if([contents count] == 2) {
            NSString *key = [contents objectAtIndex:0];
            NSString *value = [contents objectAtIndex:1];
            value = [value stringByRemovingPercentEncoding];
            if (key && value) {
                [dict setObject:value forKey:key];
            }
        }
    }
    return [NSDictionary dictionaryWithDictionary:dict];
}
/**
 *  @brief  将NSDictionary转换成url 参数字符串
 *
 *  @return url 参数字符串
 */
- (NSString *)URLQueryString{
    NSMutableString *string = [NSMutableString string];
    for (NSString *key in [self allKeys]) {
        if ([string length]) {
            [string appendString:@"&"];
        }
//        CFStringRef escaped = CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)[[self objectForKey:key] description],
//                                                                      NULL,(CFStringRef)@"!*'();:@&=+$,/?%#[]",
//                                                                      kCFStringEncodingUTF8);
        
        CFStringRef escaped = (__bridge CFStringRef)([[self objectForKey:key] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"!*'();:@&=+$,/?%#[]"]]);
        [string appendFormat:@"%@=%@", key, escaped];
        CFRelease(escaped);
    }
    return string;
}

/**
 *  @brief  将NSDictionary转换成XML 字符串
 *  @return XML 字符串
 */
- (NSString *)XMLString {
    
    NSString *xmlStr = @"<xml>";
    
    for (NSString *key in self.allKeys) {
        
        NSString *value = [self objectForKey:key];
        xmlStr = [xmlStr stringByAppendingString:[NSString stringWithFormat:@"<%@>%@</%@>", key, value, key]];
    }
    
    xmlStr = [xmlStr stringByAppendingString:@"</xml>"];
    
    return xmlStr;
}

@end
